import * as fgui from "fairygui-cc";
import { FUIAssetComponent } from "../../../../ModelView/Client/Plugins/FairyGUI/FUIAssetComponent";
import { ObjectSystemAttribute, FriendOf, ExpandOf } from "../../../../../Decorator/Decorator";
import { AwakeSystem } from "../../../../../Core/Module/EventSystem/IAwakeSystem";
import { DestroySystem } from "../../../../../Core/Module/EventSystem/IDestroySystem";
import { ETTask } from "../../../../../Support/Share/Lib/Async/ETTask";

/**
 * 使用 Expand 扩展方法
 * 
 * 必须作出以下申明，才能调用对象的扩展方法
 */
declare module "../../../../ModelView/Client/Plugins/FairyGUI/FUIAssetComponent" {

    interface FUIAssetComponent {
        Awake(): void;
        UnloadUnusedUIPackages(): void;
        Destroy(): void;
        LoadUIPackageAsync(packageName: string): Promise<fgui.UIPackage>;
        LoadUIPackageSyncInner(packageName: string);
        LoadUIPackageAsyncInner(packageName: string, callback);
        LoadTextureAsyncInner(assetName: string, callback);
        LoadAudioClipAsyncInner(assetName: string, callback);
        ReleaseAssetInner(texture): void;
    }

}

@ExpandOf(FUIAssetComponent)
export class FUIAssetComponentSystem {

    private static Awake(self: FUIAssetComponent): void {
        // byte[] LoadUIPackageSyncHandler(string packageName)
        // {
        //     return self.LoadUIPackageSyncInner(packageName);
        // }

        // void LoadUIPackageAsyncHandler(string packageName, LoadUIPackageCallback callback)
        // {
        //     self.LoadUIPackageAsyncInner(packageName, callback).Coroutine();
        // }

        // void LoadTextureAsyncHandler(string packageName, string assetName, string extension, LoadTextureCallback callback)
        // {
        //     self.LoadTextureAsyncInner(assetName, callback).Coroutine();
        // }

        // void ReleaseTextureHandler(Texture texture)
        // {
        //     self.ReleaseAssetInner(texture);
        // }

        // void LoadAudioClipAsyncHandler(string packageName, string assetName, string extension, LoadAudioClipCallback callback)
        // {
        //     self.LoadAudioClipAsyncInner(assetName, callback).Coroutine();
        // }

        // void ReleaseAudioClipHandler(AudioClip audioClip)
        // {
        //     self.ReleaseAssetInner(audioClip);
        // }

        // self.Locations = new Dictionary<int, string>();
        // self.UIAssetLoader = new DelegateUIAssetLoader(LoadUIPackageSyncHandler, LoadUIPackageAsyncHandler, LoadTextureAsyncHandler, ReleaseTextureHandler, LoadAudioClipAsyncHandler, ReleaseAudioClipHandler);
        // self.UIAssetManager = new UIAssetManager(self.UIAssetLoader, new UIPackageHelper());
    }

    private static UnloadUnusedUIPackages(self: FUIAssetComponent): void {
        // self.UIAssetManager.UnloadUnusedUIPackages();
    }

    private static Destroy(self: FUIAssetComponent): void {
        // self.UIAssetManager.Dispose();
        // self.UIAssetManager = null;
        // self.UIAssetLoader = null;

        // if (ResComponent.Instance != null && !ResComponent.Instance.IsDisposed) {
        //     foreach(string location in self.Locations.Values)
        //     {
        //         ResComponent.Instance.UnloadAsset(location);
        //     }
        // }

        // self.Locations.Clear();
    }

    private static async LoadUIPackageAsync(self: FUIAssetComponent, packageName: string): Promise<fgui.UIPackage> {
        let tcs = ETTask.Create<fgui.UIPackage>();
        fgui.UIPackage.loadPackage(`Bundles/FUI/${packageName}/${packageName}`, (err, pkg: fgui.UIPackage) => {
            console.log(err);
            tcs.SetResult(pkg);
        });
        return tcs;
        // const task = ETTask.Create<fgui.UIPackage>();
        // // self.UIAssetManager.LoadUIPackageAsync(packageName, package => { task.SetResult(package); });
        // return task;
    }

    private static LoadUIPackageSyncInner(self: FUIAssetComponent, packageName: string) {
        //     string location = "{0}{1}".Fmt(packageName, "_fui");
        // byte[] descData = ResComponent.Instance.LoadRawFileDataSync(location);
        // return descData;
    }

    private static async LoadUIPackageAsyncInner(self: FUIAssetComponent, packageName: string, callback) {
        //     string location = "{0}{1}".Fmt(packageName, "_fui");
        // byte[] descData = await ResComponent.Instance.LoadRawFileDataAsync(location);
        // callback(descData, packageName);
    }

    private static async LoadTextureAsyncInner(self: FUIAssetComponent, assetName: string, callback) {
        //     Texture res = await ResComponent.Instance.LoadAssetAsync<Texture>(assetName);

        // if (res != null)
        //     self.Locations[res.GetInstanceID()] = assetName;

        // callback(res);
    }

    private static async LoadAudioClipAsyncInner(self: FUIAssetComponent, assetName: string, callback) {
        //     AudioClip res = await ResComponent.Instance.LoadAssetAsync<AudioClip>(assetName);

        // if (res != null)
        //     self.Locations[res.GetInstanceID()] = assetName;

        // callback(res);
    }

    private static ReleaseAssetInner(self: FUIAssetComponent, texture): void {
        // if (texture == null)
        //     return;

        // const instanceId = texture.GetInstanceID();
        // if (!self.Locations.TryGetValue(instanceId, out string location))
        //     return;

        // self.Locations.Remove(instanceId);

        // if (ResComponent.Instance != null && !ResComponent.Instance.IsDisposed) {
        //     ResComponent.Instance.UnloadAsset(location);
        // }
    }

}


@FriendOf(FUIAssetComponent)
@ObjectSystemAttribute()
export class FUIAssetComponentAwakeSystem extends AwakeSystem<FUIAssetComponent> {

    Awake(self: FUIAssetComponent): void {
        self.Awake();
    }

}

@FriendOf(FUIAssetComponent)
@ObjectSystemAttribute()
export class FUIAssetComponentDestroySystem extends DestroySystem<FUIAssetComponent> {

    Destroy(self: FUIAssetComponent): void {
        self.Destroy();
    }

}